﻿using Autofac.Core.Registration;
using AutoRegistDependency.Component;
using AutoRegistDependency.Interface;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Text;

namespace AutoRegistDependency.Attributes.Condition
{
    /// <summary>
    /// 根据配置文件项决定组件是否注册特性。可以标记在方法以及类上。
    /// Determine whether the component registers feature based on the configuration file items. Can be marked on methods and classes.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    public sealed class ConditionalOnPropertyAttribute : Attribute, ICondition
    {
        /// <summary>
        /// 配置路径前缀
        /// </summary>
        public string Prefix { get; set; }
        /// <summary>
        /// 配置项name
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 配置项的值
        /// </summary>
        public string HavingValue { get; set; }

        /// <summary>
        /// 如果此配置值不存在，是否注册
        /// </summary>
        public bool MatchIfMissing { get; set; } = false;

        /// <summary>
        /// 是否忽略大小写
        /// </summary>
        public bool IgnoreCase { get; set; } = false;
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="name">配置文件内属性的名称。The name of the attribute in the configuration file.</param>
        /// <param name="havingValue">配置文件值。Profile values</param>
        /// <param name="prefix">前缀</param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <param name="matchIfMissing">如果此配置值不存在，是否注册</param>
        public ConditionalOnPropertyAttribute(string name, string havingValue, string prefix = "", bool ignoreCase=false,bool matchIfMissing=false)
        {
            Prefix = prefix;
            Name = name;
            HavingValue = havingValue;
            IgnoreCase = ignoreCase;
            MatchIfMissing = matchIfMissing;
        }

        public bool Matches(HostBuilderContext hostBuilderContext, IComponentRegistryBuilder componentRegistry, ComponentDefinition component)
        {
            if (hostBuilderContext == null)
            {
                return true;
            }
            string totalPath = !string.IsNullOrWhiteSpace(Prefix) ? $"{Prefix}:{Name}" : Name;
            var configValue = hostBuilderContext.Configuration.GetSection(totalPath).Value;
            if (string.IsNullOrEmpty(configValue))
            {
                return MatchIfMissing;
            }
            if (IgnoreCase)
            {
                return configValue.Equals(HavingValue, StringComparison.OrdinalIgnoreCase);
            }
            return configValue == HavingValue;
        }
    }
}
